package com.ksd.pug.controller.login;

import com.ksd.pug.commons.enums.ResultStatusEnumA;
import com.ksd.pug.commons.ex.PugValidationException;
import com.ksd.pug.commons.utils.fn.asserts.Vsserts;
import com.ksd.pug.commons.utils.json.FastJsonUtil;
import com.ksd.pug.commons.utils.pwd.MD5Util;
import com.ksd.pug.config.cache.EHCacheService;
import com.ksd.pug.controller.APIBaseController;
import com.ksd.pug.pojo.RoleUser;
import com.ksd.pug.pojo.SysLoginUser;
import com.ksd.pug.service.roleuser.IRoleUserService;
import com.ksd.pug.service.user.ISysLoginUserService;
import com.ksd.pug.vo.user.login.LoginUserVo;
import com.ksd.pug.vo.user.login.LoginVo;
import com.ksd.pug.vo.user.login.LogoutVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.UUID;

/**
 * @author hcl
 * @date 2022/3/16$ 23:56$
 */

@RestController
@RequiredArgsConstructor
@Slf4j
public class PassportLoginController extends APIBaseController {

    private final ISysLoginUserService userService;
    //private final IdWorkService idWorkService;
    private final EHCacheService ehCacheService;
    private final IRoleUserService roleUserService;


    //登出方法
    @PostMapping("/passport/logout")
    public boolean toLoginOut(@RequestBody LogoutVo logoutVo) {
        log.info("用户id{}",logoutVo.getUserId());
        // 删除缓存中中用户信息
        log.info("删除缓存中中用户信息{}",logoutVo.getUserId());
        redisOperator.del("xq:login:user:" + logoutVo.getUserId());
        // 删除缓存中中token
        log.info("删除缓存中中token{}",logoutVo.getUserId());
        redisOperator.del("xq:login:user:token:" + logoutVo.getUserId());
        // 本地缓存
        log.info("本地缓存{}",logoutVo.getUserId());
        ehCacheService.removeCache("xq:login:user:" + logoutVo.getUserId());
        ehCacheService.removeCache("xq:login:user:token:" + logoutVo.getUserId());
        log.info("success{}",logoutVo.getUserId());
        return true;
    }


    // 短信登录方法
    @PostMapping("/passport/login")
    public LoginUserVo toLoginReg(@RequestBody @Valid LoginVo loginVo) {
        // 1: 接受用户提交用户手机和短信
        String inputPhone = loginVo.getPhone();
        String inputSmsCode = loginVo.getSmscode();
        // 2: 获取redis缓存中的存储短信
        String cacheSmsCode = redisOperator.get("xq:login:sms:" + inputPhone);
        Vsserts.isEmptyEx(cacheSmsCode, "短信已经失效");
        // 3: 对比短信码是否正确
        if (!cacheSmsCode.equalsIgnoreCase(inputSmsCode)) {
            throw new PugValidationException(602, "你输入短信证码有误!");
        }
        // 4：开始进行业务的处理
        SysLoginUser dbUser = userService.getByPhone(inputPhone);
        // 如果dbUser，说明没有注册
        if (Vsserts.isNull(dbUser)) {
            //生成六位数的随机数
            String code = (int) ((Math.random() * 9 + 1) * 100000) + "";
            // 开始注册
            dbUser = new SysLoginUser();
            dbUser.setTelephone(inputPhone);
            dbUser.setNickname("用户"+code);
            dbUser.setUsername(inputPhone);
            dbUser.setPassword("");
            dbUser.setAvatar("https://sf6-cdn-tos.toutiaostatic.com/img/user-avatar/ccc7545b3768dd3cf09ba949e90924e5~300x300.image");
            dbUser.setMale(2);
            dbUser.setDescription("Ta什么都没有留下...");
            dbUser.setStatus(1);
            dbUser.setIsdelete(0);
            userService.saveOrUpdate(dbUser);
            //给新用户赋予普通用户的角色
            RoleUser roleUser = new RoleUser();
            roleUser.setRoleId(4L);
            roleUser.setUserId(dbUser.getId());
            roleUserService.save(roleUser);
        }

        // 5: 存在就返回
        LoginUserVo loginUserVo = new LoginUserVo();
        BeanUtils.copyProperties(dbUser, loginUserVo);
        // 6: 生成一个uuid代表token
        String tokenUuid = UUID.randomUUID().toString();
        loginUserVo.setToken(tokenUuid);
        loginUserVo.setUserId(dbUser.getId());
        // 7 : 登录成功以后，把用户信息放入到缓存中，只要是为了后续业务的需要，
        redisOperator.set("xq:login:user:" + loginUserVo.getUserId(), FastJsonUtil.toJSON(dbUser));
        // token放入缓存中去，是给同一个用户在不同的端登录。前面登录会自动全部拦截下线。只有最后一次登录的才有效。
        redisOperator.set("xq:login:user:token:" + loginUserVo.getUserId(), tokenUuid);
        // 8：而且短信码一定注册成功其实也没有任何用处，会占用redis内存空间，所有删除掉
        redisOperator.del("xq:login:sms:" + inputPhone);

        // 本地缓存
        ehCacheService.setCache("xq:login:user:" + loginUserVo.getUserId(),dbUser);
        ehCacheService.setCache("xq:login:user:token:" + loginUserVo.getUserId(), tokenUuid);


        return loginUserVo;
    }


    //密码登录方法
    @PostMapping("/passport/loginpwd")
    public LoginUserVo toLoginPwd(@RequestBody @Valid LoginVo loginVo) {
        // 1: 接受用户提交用户手机和短信
        String inputPhone = loginVo.getPhone();
        String inputPassword = loginVo.getPassword();
        //inputPhone = DesUtils.decrypt(inputPhone);
        //inputPassword = DesUtils.decrypt(inputPassword);

        //Vsserts.isFalse(ValidatorUtil.isValidatorPhone(inputPhone),"请输入正确的手机号码");
        // 4：开始进行业务的处理
        SysLoginUser dbUser = userService.getByPhone(inputPhone);
        // 如果dbUser，说明没有注册
        if (Vsserts.isNotNull(dbUser)) {
            // 查询数据的密码
            String dbPassword = dbUser.getPassword();
            // 拿用户输入的密码和数据库的密码进行比较。如果不相等直接抛出异常
            inputPassword = MD5Util.md5slat(inputPassword);
            if(!inputPassword .equalsIgnoreCase(dbPassword)){
                throw new PugValidationException(ResultStatusEnumA.USER_REG_USER_PASSWORD_CONFIRM);
            }
            // 5: 存在就返回
            LoginUserVo loginUserVo = new LoginUserVo();
            BeanUtils.copyProperties(dbUser, loginUserVo);
            // 6: 生成一个uuid代表token
            String tokenUuid = UUID.randomUUID().toString();
            loginUserVo.setToken(tokenUuid);
            loginUserVo.setUserId(dbUser.getId());


            // 7 : 登录成功以后，把用户信息放入到缓存中，只要是为了后续业务的需要，
            redisOperator.set("xq:login:user:" + loginUserVo.getUserId(), FastJsonUtil.toJSON(dbUser));
            // token放入缓存中去，是给同一个用户在不同的端登录。前面登录会自动全部拦截下线。只有最后一次登录的才有效。
            redisOperator.set("xq:login:user:token:" + loginUserVo.getUserId(), tokenUuid);
            // 8：而且短信码一定注册成功其实也没有任何用处，会占用redis内存空间，所有删除掉
            redisOperator.del("xq:login:sms:" + inputPhone);

            // 本地缓存
            ehCacheService.setCache("xq:login:user:" + loginUserVo.getUserId(),dbUser);
            ehCacheService.setCache("xq:login:user:token:" + loginUserVo.getUserId(), tokenUuid);

            return loginUserVo;
        }else{
            // 如果根据手机号码找不到用户，说明手机号码输入有误
            throw new PugValidationException(ResultStatusEnumA.USER_PWD_STATUS);
        }
    }
    //重置密码
    @PostMapping("/passport/repwd")
    public Boolean toRePwd(@RequestBody @Valid LoginVo loginVo) {
        // 1: 接受用户提交用户手机和密码
        String inputPhone = loginVo.getPhone();
        String inputPassword = loginVo.getPassword();
        SysLoginUser dbUser = userService.getByPhone(inputPhone);
        SysLoginUser user = new SysLoginUser();
        user.setId(dbUser.getId());
        inputPassword = MD5Util.md5slat(inputPassword);
        user.setPassword(inputPassword);
        return userService.updateById(user);
    }
}
